﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using Tulde.Windows.Music.ViewModel;
using System.ComponentModel;
using System.Windows.Threading;
using System.Windows.Media.Effects;

namespace Tulde.Windows.App.Controls
{
    /// <summary>
    /// Interaction logic for MediaPlayer.xaml
    /// </summary>
    public partial class MediaPlayer : UserControl
    {
        private double currentVolume;
        private bool isMuted = false;
        DispatcherTimer timer;
        bool isDragging = false;
        public event EventHandler<MediaPlayerEventArgs> TrackChanged;
        public event EventHandler<MediaPlayerEventArgs> TrackPlaying;

        private int _currentTrackIndex;
        public int CurrentTrackIndex
        {
            get
            {
                return this._currentTrackIndex;
            }
            private set
            {
                this._currentTrackIndex = value;
                this.Play();
             
            }
        }
        public Track CurrentTrack
        {
            get
            {
                if (this.CurrentTrackIndex < this.TrackCollection.Count)
                {
                    return this.TrackCollection[this.CurrentTrackIndex];
                }
                else
                {
                    this.CurrentTrackIndex = 0;
                    return this.TrackCollection[this.CurrentTrackIndex];
                }
            }
        }
        private List<Track> _trackCollection;
        public List<Track> TrackCollection
        {
            get
            {
                if (_trackCollection == null)
                {
                    _trackCollection = new List<Track>();
                }
                return _trackCollection;
            }
            set
            {
                this._trackCollection = value;
                if (this._trackCollection.Any())
                {
                    this.CurrentTrackIndex = 0;
                }
            }
        }

        protected void OnTrackChanged(Track track)
        {
            if (this.TrackChanged != null)
            {
                this.TrackChanged(this, new MediaPlayerEventArgs { Track = track });
            }
        }
        protected void OnTrackPlay(Track track)
        {
            if (this.TrackPlaying != null)
            {
                this.TrackPlaying(this, new MediaPlayerEventArgs { Track = track });
            }
        }
        public void PlayTrack(Track track)
        {
            for (int i = 0; i < this.TrackCollection.Count; i++)
            {
                if (this.TrackCollection[i].TrackId == track.TrackId)
                {
                    this.CurrentTrackIndex = i;
                    break;
                }
            }
        }
        public MediaPlayer()
        {
            InitializeComponent();
            timer = new DispatcherTimer();
            timer.Interval = TimeSpan.FromMilliseconds(200);
            timer.Tick += new EventHandler(timer_Tick);

            this.player.LoadedBehavior = MediaState.Manual;
            this.player.UnloadedBehavior = MediaState.Manual;
            this.player.MediaEnded += new RoutedEventHandler(player_MediaEnded);
            this.player.MediaFailed += new EventHandler<ExceptionRoutedEventArgs>(player_MediaFailed);
            this.player.MediaOpened += new RoutedEventHandler(player_MediaOpened);
            this.player.BufferingStarted += new RoutedEventHandler(player_BufferingStarted);
            this.volume.Value = 0.5;
            this.mute.Click += new RoutedEventHandler(mute_Click);

            this.play.Click += new RoutedEventHandler(play_Click);
            this.stop.Click += new RoutedEventHandler(stop_Click);
            this.pause.Click += new RoutedEventHandler(pause_Click);
            this.next.Click += new RoutedEventHandler(next_Click);
            this.previous.Click += new RoutedEventHandler(previous_Click);

            this.SetButtonState(false);
        }

        void mute_Click(object sender, RoutedEventArgs e)
        {
            this.Mute();
        }
        private void SetButtonState(bool enabled)
        {
            this.play.IsEnabled = enabled;
            this.next.IsEnabled = this.play.IsEnabled;
            this.previous.IsEnabled = this.play.IsEnabled;
            this.stop.IsEnabled = this.play.IsEnabled;
        }

        void previous_Click(object sender, RoutedEventArgs e)
        {
            this.Previous();
        }

        void next_Click(object sender, RoutedEventArgs e)
        {
            this.Next();
        }

        void pause_Click(object sender, RoutedEventArgs e)
        {
            this.Pause();
        }

        void stop_Click(object sender, RoutedEventArgs e)
        {
            this.Stop();
        }

        void play_Click(object sender, RoutedEventArgs e)
        {
            this.Play();
        }

        void ApplyEnter(object sender, RoutedEventArgs e)
        {
            Image b = e.Source as Image;
          
           
           // b.Background = new SolidColorBrush(Colors.Azure);
        }
        void ApplyLeave(object sender, RoutedEventArgs e)
        {
            Image b = e.Source as Image;
         
           // b.Background = new SolidColorBrush(Colors.Azure);
        }
        #region Actions
        void timer_Tick(object sender, EventArgs e)
        {
            if (!isDragging)
            {
                seekBar.Value = this.player.Position.TotalSeconds;
            }
        }
        public void Play()
        {
            this.SetButtonState(true);
            this.OnTrackChanged(this.CurrentTrack);
            this.player.Stop();
            this.play.Visibility = System.Windows.Visibility.Hidden;
            this.pause.Visibility = System.Windows.Visibility.Visible;
            this.SetProgressBar(true);

            this.status.Text = "Loading " + this.CurrentTrack.ArtistName + " - " + this.CurrentTrack.TrackTitle;
               
            this.player.Source = new Uri(this.CurrentTrack.PlayURL, UriKind.Absolute);
            this.player.Play();
        }
        public void Stop()
        {
            this.SetProgressBar(false);
            this.play.Visibility = System.Windows.Visibility.Visible;
            this.pause.Visibility = System.Windows.Visibility.Hidden;
            this.player.Stop();
        }
        public void Pause()
        {
            this.SetProgressBar(false);
            this.play.Visibility = System.Windows.Visibility.Visible;
            this.pause.Visibility = System.Windows.Visibility.Hidden;
            this.player.Pause();
        }
        public void Next()
        {
            this.CurrentTrackIndex++;
        }
        public void Previous()
        {
            this.CurrentTrackIndex--;
        }
        public void Mute()
        {
            if (this.isMuted)
            {
                this.volume.Value = this.currentVolume;
                this.player.Volume = this.currentVolume;
                this.isMuted = false;
            }
            else
            {
                
                this.currentVolume = this.player.Volume;
                this.isMuted = true;
                this.volume.Value = 0;
                this.player.Volume = 0;
            }
        }
        private BitmapImage CreateBitmapImage(string url)
        {
            BitmapImage logo = new BitmapImage();
            logo.BeginInit();
            logo.UriSource = new Uri(url);
            logo.EndInit();
            return logo;
        }
        private void seekBar_DragStarted(object sender, System.Windows.Controls.Primitives.DragStartedEventArgs e)
        {
            isDragging = true;
        }

        private void seekBar_DragCompleted(object sender, System.Windows.Controls.Primitives.DragCompletedEventArgs e)
        {
            isDragging = false;
            this.player.Position = TimeSpan.FromSeconds(seekBar.Value);
        }

        private void volume_DragStarted(object sender, System.Windows.Controls.Primitives.DragStartedEventArgs e)
        {
            isDragging = true;
        }

        private void volume_DragCompleted(object sender, System.Windows.Controls.Primitives.DragCompletedEventArgs e)
        {

            isDragging = false;
            this.player.Volume = this.volume.Value;
        }
        void player_BufferingStarted(object sender, RoutedEventArgs e)
        {

        }

       
        void mute_MouseUp(object sender, MouseButtonEventArgs e)
        {

            this.Mute();
        }

     
        void player_MediaOpened(object sender, RoutedEventArgs e)
        {


            if (this.player.NaturalDuration.HasTimeSpan)
            {
                TimeSpan ts = this.player.NaturalDuration.TimeSpan;
                seekBar.Maximum = ts.TotalSeconds;
                seekBar.SmallChange = 1;
                seekBar.LargeChange = Math.Min(10, ts.Seconds / 10);
            
                this.status.Text = "Playing " + this.CurrentTrack.ArtistName + " - " + this.CurrentTrack.TrackTitle;
                this.OnTrackPlay(this.CurrentTrack);
            }
            timer.Start();
        }
        void player_MediaEnded(object sender, RoutedEventArgs e)
        {
            this.Next();
        }

        void player_MediaFailed(object sender, ExceptionRoutedEventArgs e)
        {
            this.status.Text = e.ErrorException.Message;
        }
        public void SetProgressBar(bool state)
        {
            this.progress1.IsIndeterminate = state;
            this.progress1.IsEnabled = state;
        }
        #endregion

     
    }
    public class MediaPlayerEventArgs : EventArgs
    {
        public Track Track { get; set; }
    }
}
